package com.atguigu.gulimall.member.service.impl;

import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.member.dao.MemberDao;
import com.atguigu.gulimall.member.entity.MemberEntity;
import com.atguigu.gulimall.member.entity.MemberLevelEntity;
import com.atguigu.gulimall.member.exception.PhoneExsitException;
import com.atguigu.gulimall.member.exception.UsernameExsitException;
import com.atguigu.gulimall.member.service.MemberLevelService;
import com.atguigu.gulimall.member.service.MemberService;
import com.atguigu.gulimall.member.vo.UserLoginVo;
import com.atguigu.gulimall.member.vo.UserRegisterVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 注册会员
     *
     * @param registerVo 注册表单
     */
    @Transactional
    @Override
    public void regist(UserRegisterVo registerVo) {
        MemberEntity member = new MemberEntity();

        // 检查用户名和手机号的唯一性
        this.checkUsernameUnique(registerVo.getUserName());
        this.checkPhoneUnique(registerVo.getUserName());

        // 设置前端携带数据
        member.setMobile(registerVo.getPhone());
        member.setUsername(registerVo.getUserName());
        // 密码加密存储
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode_password = passwordEncoder.encode(registerVo.getPassword());
        member.setPassword(encode_password);

        // 设置默认会员等级
        MemberLevelEntity levelEntity = memberLevelService.getDefaultLevel();
        member.setLevelId(levelEntity.getId());

        // 设置默认信息
        member.setNickname(registerVo.getUserName());

        baseMapper.insert(member);
    }

    /**
     * 检查用户名是否唯一
     *
     * @param userName 用户名
     */
    @Override
    public void checkUsernameUnique(String userName) throws UsernameExsitException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (count > 0) {
            throw new UsernameExsitException();
        }
    }

    /**
     * 检查手机号是否唯一
     *
     * @param phone 手机号
     */
    @Override
    public void checkPhoneUnique(String phone) throws PhoneExsitException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count > 0) {
            throw new PhoneExsitException();
        }
    }

    /**
     * 用户登录
     *
     * @param vo 登录表单
     * @return 用户信息
     */
    @Override
    public MemberEntity login(UserLoginVo vo) {
        String loginacct = vo.getLoginacct();
        String password = vo.getPassword();

        // 查出该userName对应的用户信息记录
        MemberEntity entity = baseMapper.selectOne(new QueryWrapper<MemberEntity>()
                .eq("username", loginacct)
                .or()
                .eq("mobile", loginacct));
        if (entity == null || StringUtils.isBlank(entity.getPassword())) {
            return null;
        }
        String entityPassword = entity.getPassword();

        // 校验密码
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (passwordEncoder.matches(password, entityPassword)) {
            return entity;
        }
        return null;
    }

}